<?php

namespace app\common\logic;


use app\admin\system\logic\AdminLogic;
use app\model\SysAdmin;
use app\model\SysDept;
use app\model\SysRole;
use core\exception\BadException;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\facade\Db;
use think\Model;

/**
 * 逻辑层基础类
 * @package app\service
 * @method Model where($field, $op = null, $condition = null) think-orm的where方法
 * @method Model find($id) think-orm的find方法
 * @method hidden($data) think-orm的hidden方法
 * @method order($data) think-orm的order方法
 * @method save(array|object $data = [], string $sequence = null) think-orm的save方法
 * @method create(array $data, array $allowField = [], bool $replace = false, string $suffix = '') think-orm的create方法
 * @method saveAll(iterable $dataSet, bool $replace = true) think-orm的saveAll方法
 * @method insert(array $data = [], bool $getLastInsID = false) think-orm的insert方法
 * @method insertAll(array $dataSet = [], int $limit = 0) think-orm的insertAll方法
 * @method update($data, $where, $allow = []) think-orm的update方法
 * @method destroy($id) think-orm的destroy方法
 * @method select() think-orm的select方法
 * @method count($data) think-orm的count方法
 * @method max($data) think-orm的max方法
 * @method min($data) think-orm的min方法
 * @method sum($data) think-orm的sum方法
 * @method avg($data) think-orm的avg方法
 */
class BaseLogic
{
    /**
     * 模型注入
     * @var Model
     */
    protected $model;

    /**
     * @var bool 数据边界启用状态
     */
    protected $scope = false;

    //1=全部可见 2=本人可见 3=所在部门可见 4=所在部门及子级可见 5=选择的部门可见
    // 所有数据权限
    public const ALL_SCOPE = 1;
    // 本人数据权限
    public const SELF_SCOPE = 2;
    // 本部门数据权限
    public const SELF_DEPT_SCOPE = 3;
    // 本部门及子部门数据权限
    public const DEPT_BELOW_SCOPE = 4;
    // 自定义数据权限
    public const CUSTOM_SCOPE = 5;

    public function init()
    {

    }

    /**
     * 数据权限处理
     * @param $query
     * @return mixed
     */
    public function userDataScope($query)
    {
        $adminInfo = AdminLogic::getCurrentLogicAdmin(request()->uid);
        if (!$adminInfo) {
            throw new BadException('数据权限读取失败');
        }
        $roles = SysRole::where([
            ['id', 'in', strToArr($adminInfo['role_ids'])],
            ['status', '=', 1]
        ]);
        $admin_dept_id = $adminInfo['dept_id'];
        $scopeUserIds = [];
        foreach ($roles as $role) {
            $data_scope = $role['data_type'];
            switch ($data_scope) {
                case self::ALL_SCOPE:
                    return $query;
                case self::CUSTOM_SCOPE:
                    $ids = SysAdmin::where('dept_id', 'in', strToArr($role['dept_ids']))->column('id');
                    $scopeUserIds = array_merge($scopeUserIds, $ids);
                    break;
                case self::SELF_DEPT_SCOPE:
                    $ids = SysAdmin::where('dept_id', 'in', $admin_dept_id)->column('id');
                    $scopeUserIds = array_merge($scopeUserIds, $ids);
                    break;
                case self::DEPT_BELOW_SCOPE:
                    $sonIds = SysDept::where(Db::raw('find_in_set(:id,path)'))->bind([
                        'id' => $admin_dept_id
                    ])->column('id');
                    $deptIds = array_merge([$admin_dept_id], ...$sonIds);
                    $ids = SysAdmin::where('dept_id', 'in', $deptIds)->column('id');
                    $scopeUserIds = array_merge($scopeUserIds, $ids);
                    break;
                case self::SELF_SCOPE:
                    $scopeUserIds = array_merge($scopeUserIds, [$adminInfo['id']]);
                    break;
                default:
                    break;
            }
        }
        return $query->where('create_by_id', 'in', array_unique($scopeUserIds));
    }

    /**
     * 数据库事务操作
     * @param callable $closure
     * @param bool $isTran
     * @return mixed
     */
    public function transaction(callable $closure, bool $isTran = true)
    {
        return $isTran ? Db::transaction($closure) : $closure();
    }


    /**
     * 搜索器搜索
     * @param array $searchWhere
     * @return Model
     */
    public function search(array $searchWhere = [])
    {
        return $this->model->where($searchWhere);
    }

    /**
     * 分页查询数据
     * @param $query
     * @param bool $isAll
     * @return array
     * @throws BadException
     */
    public function getPageList($query, $isAll = false)
    {
        $form = request()->getForm();
        if ($this->scope) {
            $query = $this->userDataScope($query);
        }
        if ($isAll) {
            return $query->select()->toArray();
        }
        return $query->paginate([
            'page' => $form->getPage(),
            'list_rows' => $form->getPageSize(),
        ])->toArray();
    }

    /**
     * 获取全部数据
     * @param $query
     * @return mixed
     */
    public function getAll($query)
    {
        $orderBy = request()->input('orderBy') ? request()->input('orderBy') : $this->model->getPk();
        $orderType = request()->input('orderType') ? request()->input('orderType') : 'ASC';
        if ($this->scope) {
            $query = $this->userDataScope($query);
        }
        $query->order($orderBy, $orderType);
        return $query->select()->toArray();
    }

    /**
     * 获取全部数据
     * @param $where
     * @param string $field
     * @param string $order
     * @return mixed
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function getList($where = [], $field = "*", $order = "")
    {
        $query = $this->model->where($where);
        if ($this->scope) {
            $query = $this->userDataScope($query);
        }
        return $query->field($field)->order($order)->select()->toArray();
    }

    /**
     * 获取单条
     * @param $where
     * @param string $field
     * @return mixed
     */
    public function getInfo($where, $field = '*')
    {
        return $this->model->where($where)->field($field)->find()->toArray() ?? [];
    }

    /**
     * @param $where
     * @return mixed
     */
    public function getCount($where)
    {
        return $this->model->where($where)->count();
    }

    /**
     * @param $where
     * @return mixed
     */
    public function deleteByWhere($where)
    {
        return $this->model->where($where)->delete();
    }

    /**
     * @return Model
     */
    public function getModel()
    {
        $modelClass = get_class($this->model);
        return new $modelClass;
    }

    /**
     * 方法调用
     * @param $name
     * @param $arguments
     * @return mixed
     */
    public function __call($name, $arguments)
    {
        return call_user_func_array([$this->model, $name], $arguments);
    }

}